home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / ppm / ppmtopj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-06  |  7.1 KB  |  255 lines

  1. /* ppmtopj.c - convert a portable pixmap to an HP PainJetXL image
  2. **
  3. ** Copyright (C) 1990 by Christos Zoulas (christos@ee.cornell.edu)
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "ppm.h"
  14.  
  15. /*
  16.  * XXX: Only 8.5 x 11 paper
  17.  */
  18. #define WIDTH      8.5
  19. #define HEIGHT      11.0
  20. #define DPI      180
  21. #define XPIX      ((int) ((DPI * WIDTH + 7) / 8) << 3)
  22. #define YPIX      ((int) ((DPI * HEIGHT + 7) / 8) << 3)
  23.  
  24. #define C_RESET             "\033E"
  25. #define C_RENDER             "\033*t%dJ"
  26. # define C_RENDER_NONE            0
  27. # define C_RENDER_SNAP            1
  28. # define C_RENDER_BW            2
  29. # define C_RENDER_DITHER        3
  30. # define C_RENDER_DIFFUSE        4
  31. # define C_RENDER_MONODITHER        5
  32. # define C_RENDER_MONODIFFUSE        6
  33. # define C_RENDER_MONO_CL_DITHER    5
  34. # define C_RENDER_MONO_CL_DIFFUSE    6
  35. #define C_BACK_SCALE            "\033*t%dK"
  36. # define C_BACK_SCALE_LIGHT        0
  37. # define C_BACK_SCALE_DARK        1
  38. #define C_GAMMA                "\033*t%dI"
  39. #define C_IMAGE_WIDTH            "\033*r%dS"
  40. #define C_IMAGE_HEIGHT            "\033*r%dT"
  41. #define C_DATA_PLANES            "\033*r%dU"
  42. #define C_TRANS_MODE            "\033*b%dM"
  43. # define C_TRANS_MODE_STD        0
  44. # define C_TRANS_MODE_RLE        1
  45. # define C_TRANS_MODE_TIFF        2
  46. #define C_SEND_PLANE            "\033*b%dV"
  47. #define C_LAST_PLANE            "\033*b%dW"
  48. #define C_BEGIN_RASTER            "\033*r%dA"
  49. # define C_BEGIN_RASTER_MARGIN        0
  50. # define C_BEGIN_RASTER_ACTIVE        1
  51. # define C_BEGIN_RASTER_NOSCALE        0
  52. # define C_BEGIN_RASTER_SCALE        2
  53. #define C_END_RASTER            "\033*r%dC"
  54. # define C_END_RASTER_UNUSED        0
  55. #define C_RESOLUTION            "\033*t%dR"
  56. # define C_RESOLUTION_90DPI        90
  57. # define C_RESOLUTION_180DPI        180
  58. #define C_MOVE_X            "\033*p+%dX"
  59. #define C_MOVE_Y            "\033*p+%dY"
  60.  
  61. char *testimage;
  62.  
  63. static char *rmode[] = { "none", "snap", "bw", "dither", "diffuse", 
  64.              "monodither", "monodiffuse", "clusterdither", 
  65.              "monoclusterdither", NULL };
  66.  
  67. /*
  68.  * Run-length encoding for the PaintJet. We have pairs of <instances>
  69.  * <value>, where instances goes from 0 (meaning one instance) to 255
  70.  * If we are unlucky we can double the size of the image.
  71.  */
  72. static int
  73. compress_row(op, oe, cp)
  74. unsigned char *op, *oe, *cp;
  75. {
  76.     unsigned char *ce = cp;
  77.     while ( op < oe ) {    
  78.     unsigned char px = *op++;
  79.     unsigned char *pr = op;
  80.     while ( op < oe && *op == px && op - pr < 255) op++;
  81.     *ce++ = op - pr;
  82.     *ce++ = px;
  83.     }
  84.     return ce - cp;
  85. }
  86.  
  87. void main(argc, argv)
  88. int argc;
  89. char *argv[];
  90. {
  91.     pixel **pixels;
  92.     FILE *ifp;
  93.     int argn, rows, cols, colors, r, c, k, m, p;
  94.     pixval maxval;
  95.     int planes = 3;
  96.     unsigned char *obuf, *op, *cbuf;
  97.     int render_mode = C_RENDER_NONE;
  98.     int back_scale = C_BACK_SCALE_DARK;
  99.     int gamma = 0;
  100.     int mode = C_TRANS_MODE_STD;
  101.     int deciwidth = 0, deciheight = 0;
  102.     int center = 0;
  103.     int xoff = 0, yoff = 0;
  104.     /*
  105.      * XXX: Someday we could make this command line options.
  106.      */
  107.     int posscale = C_BEGIN_RASTER_MARGIN | C_BEGIN_RASTER_NOSCALE;
  108.     int resolution = C_RESOLUTION_180DPI;
  109.  
  110.     char *usage = "[-center] [-xpos <pos>] [-ypos <pos>] [-gamma <val>] [-back <dark|lite>] [-rle] [-render <none|snap|bw|dither|diffuse|monodither|monodiffuse|clusterdither|monoclusterdither>] [ppmfile]";
  111.  
  112.     ppm_init( &argc, argv );
  113.  
  114.     argn = 1;
  115.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  116.         {
  117.         if ( pm_keymatch(argv[argn],"-render",2) && argn + 1 < argc )
  118.         {
  119.         ++argn;
  120.         for (r = 0; rmode[r] != NULL; r++)
  121.              if (strcmp(rmode[r], argv[argn]) == 0)
  122.              break;
  123.         if (rmode[r] != NULL)
  124.             render_mode = r;
  125.         else
  126.             pm_usage(usage);
  127.         }
  128.         else if ( pm_keymatch(argv[argn],"-back",2) && argn + 1 < argc )
  129.         {
  130.         ++argn;
  131.         if (strcmp(argv[argn], "dark") == 0)
  132.             back_scale = C_BACK_SCALE_DARK;
  133.         else if (strcmp(argv[argn], "lite") == 0)
  134.             back_scale = C_BACK_SCALE_LIGHT;
  135.         else
  136.             pm_usage(usage);
  137.         }
  138.         else if ( pm_keymatch(argv[argn],"-gamma",2) && argn + 1 < argc )
  139.         {
  140.         ++argn;
  141.         if ( sscanf( argv[argn], "%d",&gamma ) != 1 )
  142.             pm_usage( usage );
  143.         }
  144.         else if ( pm_keymatch(argv[argn],"-xpos",2) && argn + 1 < argc )
  145.         {
  146.         ++argn;
  147.         if ( sscanf( argv[argn], "%d",&xoff ) != 1 )
  148.             pm_usage( usage );
  149.         }
  150.         else if ( pm_keymatch(argv[argn],"-ypos",2) && argn + 1 < argc )
  151.         {
  152.         ++argn;
  153.         if ( sscanf( argv[argn], "%d",&yoff ) != 1 )
  154.             pm_usage( usage );
  155.         }
  156.         else if (pm_keymatch(argv[argn],"-rle",2))
  157.         mode = C_TRANS_MODE_RLE;
  158.         else if (pm_keymatch(argv[argn],"-center",2))
  159.         center = 1;
  160.         else
  161.         pm_usage( usage );
  162.         ++argn;
  163.         }
  164.  
  165.     if ( argn < argc )
  166.         {
  167.         ifp = pm_openr( argv[argn] );
  168.         ++argn;
  169.         }
  170.     else
  171.         ifp = stdin;
  172.  
  173.     if ( argn != argc )
  174.         pm_usage( usage );
  175.  
  176.     pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
  177.  
  178.     pm_close( ifp );
  179.     obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char));
  180.     cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char));
  181.  
  182.         if (cols > XPIX || rows > YPIX)
  183.         pm_message("image too large for page");
  184.         if (center) {
  185.         if (xoff || yoff)
  186.         pm_error("cannot specify both center and position");
  187.         xoff = (XPIX - cols) / 2;
  188.         yoff = (YPIX - rows) / 2;
  189.     }
  190.  
  191.     (void) fprintf (stdout, C_RESET);
  192.     /*
  193.      * Set the resolution before begin raster otherwise it
  194.      * does not work.
  195.      */
  196.     (void) fprintf (stdout, C_RESOLUTION, resolution);
  197.     (void) fprintf (stdout, C_BEGIN_RASTER, posscale);
  198.     if (xoff)
  199.         (void) fprintf (stdout, C_MOVE_X, xoff);
  200.     if (yoff)
  201.         (void) fprintf (stdout, C_MOVE_Y, yoff);
  202.     (void) fprintf (stdout, C_TRANS_MODE, mode);
  203.     (void) fprintf (stdout, C_RENDER, render_mode);
  204.     (void) fprintf (stdout, C_BACK_SCALE, back_scale);
  205.     (void) fprintf (stdout, C_GAMMA,     gamma);
  206.     (void) fprintf (stdout, C_IMAGE_WIDTH, cols);
  207.     (void) fprintf (stdout, C_IMAGE_HEIGHT, rows);
  208.     (void) fprintf (stdout, C_DATA_PLANES, 3);
  209.  
  210.         for (r = 0; r < rows; r++)
  211.         /* for each primary */
  212.         for (p = 0; p < 3; p++) {
  213.         switch (p) {
  214.         case 0:
  215.             for (c = 0, op = &obuf[-1]; c < cols; c++) {
  216.             if ((k = (c & 7)) == 0)
  217.                 *++op = 0;
  218.             if (PPM_GETR(pixels[r][c]) > maxval / 2)
  219.                 *op |= 1 << (7 - k);
  220.             }
  221.             break;
  222.         case 1:
  223.             for (c = 0, op = &obuf[-1]; c < cols; c++) {
  224.             if ((k = (c & 7)) == 0)
  225.                 *++op = 0;
  226.             if (PPM_GETG(pixels[r][c]) > maxval / 2)
  227.                 *op |= 1 << (7 - k);
  228.             }
  229.             break;
  230.         case 2:
  231.             for (c = 0, op = &obuf[-1]; c < cols; c++) {
  232.             if ((k = (c & 7)) == 0)
  233.                 *++op = 0;
  234.             if (PPM_GETB(pixels[r][c]) > maxval / 2)
  235.                 *op |= 1 << (7 - k);
  236.             }
  237.             break;
  238.         }
  239.         ++op;
  240.         if (mode == C_TRANS_MODE_RLE) {
  241.             k = compress_row(obuf, op, cbuf);
  242.             op = cbuf;
  243.         }
  244.         else {
  245.             k = op - obuf;
  246.             op = obuf;
  247.         }
  248.         (void) fprintf (stdout, p == 2 ? C_LAST_PLANE : C_SEND_PLANE, k);
  249.         (void) fwrite(op, 1, k, stdout);
  250.         }
  251.     (void) fprintf (stdout, C_END_RASTER, C_END_RASTER_UNUSED);
  252.     pm_close (stdout);
  253.     exit(0);
  254. }
  255.